/************************************************************************************************************************************************
 *   Copyright (C) 2008 by Denjs                                                                                                                *
 *   dplsoft@pisem.net                                                                                                                          *
 *   http://qdroid.berlios.de                                                                                                                   *
 * -----------------------------------------------------------------------                                                                      *
 *   This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or (at your option) any later version.                                      *
 *   This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.                                 *
 *   You should have received a copy of the GNU General Public License along with this program; if not, write to the                            *
 *   Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                                                  *
 * -------------------------------------------------------------------------------------------------------------------------------------------- *
 *     Эта программа является свободным программным обеспечением; вы можете распространять её и/или модифицировать в соответствии с лицензией   *
 *   GNU General Public License  (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU) версии 2.0 или более поздней - на ваш выбор.                         *
 *     Эта программа распространяется  в надежде что она будет вам полезна, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, подразумеваемых или явных; без обещаний *
 *   полезности или применимости в конкретных условиях. Вы используете  данное ПО на свой страх и риск и сами полностью несете                  *
 *   ответственность за последствия. См. GNU General Public License (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU).                                  *
 *     Вы должны получить копию GNU General Public License (УНИВЕРСАЛЬНАЯ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ GNU)с данным ПО; Если этого не случилось,       *
 *   обратитесь в Фонд Свободного Программного Обеспечения :                                                                                    *
 *   Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                                                  *
 * -------------------------------------------------------------------------------------------------------------------------------------------  *
 * Замечания для территории России: в соответствии с ГК РФ часть 4, начиная использовать данную программу (исполняемые файлы или исходные       *
 * тексты) вы автоматически соглашаетесь с данной лицензией.
 ************************************************************************************************************************************************/
/*::[[@stdinreader]] [[:buildin_classes]]
**stdInReader** - класс для работы с потоками STDIN|STDOUT|STDERR.
. \n
См также:
  * [[childprocess]] ((класс для запуска дочерненго процесса. предоставляет интерфейс для работы с потоками ввода-вывода дочернего процесса);

Общие характеристики:
  * имя конструктора QtScript: -не предоставляет- ;
    * QDroid создает единстввенный объект данного класса, \n доступный через переменную [[stdstreamsgate|StdStreamsGate]]
  * C++ имя класса : stdInReader наследован от QThread ;
  * Являетля встроенным классом.
  * Требует для нормальной работы загруженного расширения : [[qdlib_bytearray]] (TODO:сделать bytearray встроенным классом!)

----
  ver.2009.09.23 (альфа) 
  ver.2009.09.14 (естественно альфа, но работает и это главное) 

*/

//  UTF-8 russian encoded file


#include <QApplication>
#include <QtCore> 
#include <QThread> 
#include <QFile> 
#include <QDebug> 

//as in OTPD)
// Linux :
#if defined (Q_WS_X11) 
	/* nothing needs to be included here yet...*/
// Win :
#elif defined (Q_WS_WIN)
	// for Sleep() :
	#include <windows.h>
// Mac:
#elif defined (Q_WS_MAC)
	/* NOT SUPPORTED THIS VERSION */
#else
	/* NOT SUPPORTED THIS VERSION */
#endif


/*::---- 
===Общее описание===

Сценарий использования включает следующие команды:
сначала int stdInReader::[[#open|open]](); - производится попытка открыть файловые дискрипторы потоков ввода/вывода; \n 
Потом void stdInReader::[[#start|start]](); - начинается обработка данных. \n 
При этом, генерируемые сигналы о поступлении данных на STDIN зависят от реима кеширования. 
    * Если режим кеширования включен - то при поступлении данных посылается сигнал stdIn_readyRead \n и данные надо считать функцией [[stdin_Read|stdin_Read]] 
    * Если режим кеширования отключен - до данные пересылаются вместе с сигналом [[stdIn_received|stdIn_received]].
Что-бы приостановить обработку данных выполните void stdInReader::[[stop|stop]](); \n 
Что бы закрыть дискрипторы потоков ввода вывода, выполните int stdInReader::[[close|close]](); \n 
\n 
Родительская среда может закрыть поток ввода со своей стороны. Таким образом например некоторые утилиты Linux сообщают, 
что это все данные которые они хотели передать и более данных не будет. после получения сигнала [[stdIn_StreamClosed|stdIn_StreamClosed]].

---- 
====Методы и свойства класса====
*/

#define maxCashSize 16383

class stdInReader : public QThread //::====$0 $1====\n   ***$*** \n  
 {
 Q_OBJECT

 public: //::===Секция $* (С++)===
	int DebugLevel;//::  * **$*** \n уровень отладки 0-нет логов; 5-пошаговый с дампами переменных. некоторые режимы могут быть не реализованы.
	stdInReader(QObject * parent = 0);//::  * **$*** \n конструктор
	void run(); //::  * **$*** \n запуск потока на выполение.

 signals: //::===Секция $* (С++\QtScript)===
	void stdIn_received(const QByteArray &data); //::  * **$*** \n получены данные на STDIN. С сигналом присылает данные . генерируется только когда режим кеширования отключен.
	void stdIn_readyRead();		//::  * **$*** \n сигнал о том, что есть данные для чтения в приемном буфере. генерируется при включенном режиме кеширования.
	void stdIn_CashOverflow();	//::  * **$*** \n переполнениее входного кеша. данные не будут приниматься до очищения стека. Генерируется только при вклченном режиме кеширования.
        void stdReader_Opened();	//::  * **$*** \n Канал чтения STDIN открыт.
        void stdReader_Closed();	//::  * **$*** \n Канал чтения STDIN закрыт.
        void stdIn_StreamClosed();	//::  * **$*** \n Входной поток закрыт внешним приложением (родительским).Больше данных на STDIN не будет.
	void stdIn_ChangedCashMode(bool stdInCashMode);//::  * **$*** \n отсылается при изменении режима кеширования при пересылке данных.
	
 public slots: //::===Секция $* (С++\QtScript)===
	int open(bool _needAllStreams=false); //::  * **$*** \n запустить потоки чтения и записи и перейти в режим готовности к выполнения.
	//::^Возвращаемые значения ^^
	//::| 1 |already opened (if some errors was happened, but not critical) |
	//::| 0 |of all ok |
	//::|error code is summ of next values: ||
	//::|-1  if can`t oopen stdIn ||
	//::|-2  if can`t oopen stdOut ||
	//::|-4  if can`t oopen stdErr ||
	
	int close(bool failedInit=false);//::  * **$*** \n  закрыть все потоки

/**/	int send_StdOut(const QByteArray &_data);//<::  * **$*** \n Отослать данные на STDOUT
/**/	int send_StdErr(const QByteArray &_data);//<::  * **$*** \n Отослать даннын на STDERR
	/* start - standart slot*/
	void stop();//::  * **$*** \n  Остановить обработку потоков.(но не закрыть файловые дискрипторы)

	QByteArray stdin_Read(int maxSize);//::  * **$*** \n Прочитать с потока STDIN данные.
	int stdin_GetCashSize();//::  * **$*** \n получить размер кеша
	bool sdtin_waitFirReadyRead(int maxTimeMs);//::  * **$*** \n ожидать поступления данных maxTimeMs милисекунд.
//	void changedCashMode(bool stdInCashMode); //  * **$*** \n получить текущий режим пересылки данных.
	void stdIn_SetCachedMode();	//::  * **$*** \n установить [[режим кеширования при пересылке данных]] \n при послуплении дангных будет инициироваться сигнал что послупили данные, и далее надо будет из считать
	void stdIn_SetDataFlowMode();	//::  * **$*** \n установить [["прямоточный" режим пересылки данных]].\n поступающие данные будут отсылаться вместе с сигналом 
	
 private: 
	QFile stdIn;
	QFile stdOut;
	QFile stdErr;
	QByteArray data;
	bool inited;

	void from_stdin_buffer(QByteArray Message);//внутренний обработчик данных. он же занимается буфризацией
	int sleepMS( unsigned int time);

	QByteArray stdInCash;// кеш для 
	bool stdInCashMode;//
	bool stdin_ReadyRead;

 };
